#include "GameOfLife.h"

Game::Game(int row, int col, int percent)
	: _row(row)
	, _col(col)
	, _map(new CELL* [row] {})
{
	srand((unsigned int)time(nullptr));
	for (int i = 0; i < _row; i++)
	{
		_map[i] = (CELL*)operator new(sizeof(CELL) * _col);
		for (int j = 0; j < _col; j++)
			new(_map[i] + j)CELL(percent);
	}
}

Game::Game(const Game& g)
	: _row(g._row)
	, _col(g._col)
	, _map(new CELL* [g._row] {})
{
	for (int i = 0; i < _row; i++)
	{
		_map[i] = new CELL[g._col] {};
		memcpy(_map[i], g._map[i], sizeof(CELL) * g._col);
	}
}

Game& Game::operator=(const Game& g)
{
	if (this != &g)
	{
		*((size_t*)&_row) = g._row;
		*((size_t*)&_col) = g._col;
		_map = new CELL * [_col] {};
		for (int i = 0; i < _row; i++)
		{
			_map[i] = new CELL[_col]{};
			memcpy(_map[i], g._map[i], sizeof(CELL) * g._col);
		}
	}
	return *this;
}

void Game::SetRoundLife(int r, int c)
{
	_map[r][c].nums = 0;
	for (int i = -1; i <= 1; i++)
	{
		for (int j = -1; j <= 1; j++)
		{
			if (i == 0 && j == 0)
				continue;
			if (r + i < 0 || r + i >= _row || c + j < 0 || c + j >= _col)
				continue;
			if (_map[r + i][c + j].state == CELL::STATE::LIFE)
				_map[r][c].nums++;
		}
	}
}

void Game::SetMap()
{
	for (int i = 0; i < _row; i++)
	{
		for (int j = 0; j < _col; j++)
			SetRoundLife(i, j);
	}
}

void Game::Evolution()
{
	SetMap();
	for (int i = 0; i < _row; i++)
	{
		for (int j = 0; j < _col; j++)
		{
			if (_map[i][j].nums == 3)
				_map[i][j].state = CELL::STATE::LIFE;
			else if (_map[i][j].nums < 2 || _map[i][j].nums > 3)
				_map[i][j].state = CELL::STATE::DEAD;
			else
				_map[i][j].state = _map[i][j].state;
		}
	}
}

std::ostream& operator<<(std::ostream& out, const Game& g)
{
	g.Display();
	return out << std::endl;
}

std::istream& operator>>(std::istream& in, Game& g)
{
	int row = 0, col = 0, percent = 0;
	in >> row >> col >> percent;
	g = Game(row, col, percent);
	return in;
}
